#ifndef __MACHINE_H__
#define __MACHINE_H__

#include <py/obj.h>
#include <stdint.h>

#include "wm_hal.h"
#include "fifo.h"


//
// 宏定义
//

// 检查串口是否初始化完成
#define uart_init_detect(uart_obj, msg, ...) do{                                        \
    if(!self->is_enabled){                                                              \
       mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT(msg), __VA_ARGS__);         \
    }                                                                                   \
}while(0)

//
// 数据结构
//

// pyb串口数据结构
typedef struct _pyb_uart_obj_t {
    mp_obj_base_t base;
	UART_HandleTypeDef huart;             // 串口描述结构
	bool is_enabled : 1;	
    uint16_t uart_id;                     // 串口编号	
    uint16_t timeout;                     // timeout waiting for first char
	uint8_t  rcache[UART_FIFO_FULL+1];    // 使用中断进行数据收发, 串口接收需要有cache, 收完才放入队列(read_buf)  

    fifo_t fifo;                          // 队列描述结构
    //uint16_t read_buf_len;              // len in chars; buf can hold len-1 chars
    //volatile uint16_t read_buf_head;    // indexes first empty slot
    //volatile uint16_t read_buf_tail;    // indexes first full slot (not full if equals head)
    //void *read_buf;                     // 对于W80X而言, 就是uint8_t类型, 每帧只传输8个数据位
    
    //uint16_t mp_irq_trigger;            // user IRQ trigger mask
    //uint16_t mp_irq_flags;              // user IRQ active IRQ flags
    //struct _mp_irq_obj_t *mp_irq_obj;   // user IRQ object
}pyb_uart_obj_t;


// Timer数据结构
typedef struct _machine_timer_obj_t {
    mp_obj_base_t base;
    TIM_HandleTypeDef htim;    // 定时器描述结构
	bool is_enabled : 1;	
    uint8_t timer_id;          // 定时器ID, 0~5
    mp_obj_t callback;         // 定时器回调函数
}machine_timer_obj_t;


// PWM数据结构

typedef struct _pwm_stat_bit_desc_t{  /* 状态位(bit)与对应的显示信息(info) */
    uint8_t bit;
	const char* info;
}pwm_stat_bit_desc_t;

typedef struct _pwm_stat_desc_t{    /* 描述每一路PWM要检测的状态位(machine_pwm_obj_t::stat) */
	const uint8_t cnt[5];
	const pwm_stat_bit_desc_t* ch[5];
}pwm_stat_desc_t;

typedef struct _pwm_cap_desc_t{    /* PWM输入捕获相关数据结构 */
    uint32_t capbuf[20];
	DMA_HandleTypeDef hdma;
}pwm_cap_desc_t;

typedef struct _machine_pwm_obj_t   /* PWM数据结构 */
{
    mp_obj_base_t base;
    PWM_HandleTypeDef hpwm[MICROPY_HW_MAX_PWM_CNT]; 
    uint16_t stat;             // bit[0:4] - PWM[0:4]独立位,  bit5 - PWM[0:1]输出同步, bit6 - PWM[2:3]输出同步, bit7 - PWM[0:4]输出同步
                               // bit8 - PWM[0:1]互补输出, bit9 - PWM[2:3]互补输出, bit10 - PWM0用于输入捕获, bit11 - PWM4用于输入捕获
    bool reset_module;         // 是否复位整个PWM模块
    pwm_cap_desc_t cap[2];     // 输入捕获描述结构, [0]-PWM0, [1]-PWM4

}machine_pwm_obj_t;

//
// RTC数据结构
//
typedef struct _machine_rtc_obj_t {
    mp_obj_base_t base;
    RTC_TimeTypeDef time;
    PMU_HandleTypeDef hpmu;
	int timezone;             /* timezone, china is utc+8 */
	mp_obj_t callback;        // alarm callback func
}machine_rtc_obj_t;

//
// GPIO数据结构
//

typedef struct _machine_pin_obj_t{
	 mp_obj_base_t base;
	 uint8_t pin;
	 uint8_t mode;
	 uint8_t pull;
     //uint8_t stat;  // bit0: 1-hardirq, 0-softirq, 默认使用硬件中断
	 mp_obj_t callback;
}machine_pin_obj_t;

//
// SPI数据结构
//
typedef struct _machine_hard_spi_obj_t {
    mp_obj_base_t base;
    SPI_HandleTypeDef hspi;
    DMA_HandleTypeDef hdma;     /* DMA分时复用(当前时刻只能用于read或write状态) */
    uint8_t dmastat;            /* DMA标志, 0-DMA空闲, R/W, 1-DMA写操作, 2-DMA读操作 */
    mp_obj_t callback;          /* 收发完成回调函数 */
}machine_hard_spi_obj_t;


//
// 全局变量
//
extern const mp_obj_type_t pyb_uart_type;
extern const mp_obj_type_t machine_timer_type;
extern const mp_obj_type_t machine_pwm_type ;
extern const mp_obj_type_t machine_rtc_type;
extern const mp_obj_type_t machine_pin_type;
extern const mp_obj_type_t mp_machine_soft_spi_type;
extern const mp_obj_type_t machine_lspi_type;   // hspi - W806只能做位从机, lspi - 最多20MB

//
// 全局函数
//
extern USART_TypeDef* _get_uart_by_id(int nr);
extern int _get_act_baudrate(pyb_uart_obj_t* self);
extern bool _is_uart_exists(int uart_id);
extern const char* gpio_search(uint8_t pin, bool is_name, int k);

#endif